_CS_IDLE = 'Idle'
import urllib2, httplib
from urllib2 import URLError, addinfourl
import socket
import socks_proxy as socks

def _httplib_connect(self):
        """Connect to the host and port specified in __init__."""
        msg = "getaddrinfo returns an empty list"
        for res in socket.getaddrinfo(self.host, self.port, 0,
                                      socket.SOCK_STREAM):
            af, socktype, proto, canonname, sa = res
            try:
                #hacked
                if hasattr(self, '_socks'):
                    self.sock =self._socks
                else:
                    self.sock = socket.socket(af, socktype, proto)
                
                if self.debuglevel > 0:
                    print "connect: (%s, %s)" % (self.host, self.port)

                #print 'start connect server ...'
                self.sock.connect(sa)
                #print 'connect server end'
            except socket.error, msg:
                if self.debuglevel > 0:
                    print 'connect fail:', (self.host, self.port)
                if self.sock:
                    self.sock.close()
                self.sock = None
                continue
            break
        if not self.sock:
            raise socket.error, msg
httplib.HTTPConnection.connect=_httplib_connect

def _do_open(self, http_class, req):
        host = req.get_host()
        if not host:
            raise URLError('no host given')

        h = http_class(host) # will parse host:port
        #add
        if hasattr(req, '_socks'):
            h._socks=req._socks
        #end

        h.set_debuglevel(self._debuglevel)

        headers = dict(req.headers)
        headers.update(req.unredirected_hdrs)

        headers["Connection"] = "close"
        headers = dict(
            (name.title(), val) for name, val in headers.items())
        try:
            h.request(req.get_method(), req.get_selector(), req.data, headers)
            r = h.getresponse()
        except socket.error, err: # XXX what error?
            raise URLError(err)

        r.recv = r.read
        fp = socket._fileobject(r)

        resp = addinfourl(fp, r.msg, req.get_full_url())
        resp.code = r.status
        resp.msg = r.reason
        return resp

urllib2.AbstractHTTPHandler.do_open=_do_open

class ProxyProcessor(urllib2.BaseHandler):
    def __init__(self, host, port, p_type=None):
        self._host=host
        self._port=port
        self._p_type=(p_type or socks.PROXY_TYPE_SOCKS5)

    def http_request(self, request):
        s = socks.socksocket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0)
        s.setproxy(self._p_type, self._host, self._port)

        request._socks=s

        return request

    def http_response(self, request, response):
        return response

    https_request = http_request
    https_response = http_response
